﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace Topro.DataAccess.Impl
{
    using Topro.Entity;
    using Topro.Entity.Enum;
    using Topro.Entity.Query;
    using Topro.Entity.Response;
    using Topro.Entity.Table;
    using Topro.Enum;
    using Topro.Libraries.Data;
    using Topro.Libraries.Transaction;

    public class ASRSJOBImpl : Base, IASRSJOB
    {
        /// <summary>
        /// 获取指令
        /// </summary>
        /// <returns></returns>
        public ASRSJOBResonse GetById(int id)
        {
            var sql = "select * from asrsjob where Id=@Id";

            var list = DBContext.Sql(sql)
                                .Parameter("Id", id)
                                .QuerySingle<ASRSJOBResonse>();
            return list;
        }

        /// <summary>
        /// 获取指令
        /// </summary>
        /// <param name="orderType">类型</param>
        /// <param name="containerCode">容器</param>
        /// <param name="status">状态</param>
        /// <param name="stationNo">站台</param>
        /// <returns></returns>
        public ASRSJOBResonse GetSingle(ASRSJOBQuery query)
        {
            var list = DBContext.Select<ASRSJOBResonse>("*").From("asrsjob");
            //查询条件
            Action<string, string, object> setWhere = (@where, name, value) => list.AndWhere(@where).Parameter(name, value);

            if (string.IsNullOrEmpty(query.ORIPORT))
            {
                setWhere("ORIPORT = @ORIPORT", "ORIPORT", query.ORIPORT);
            }

            return list.QuerySingle();
        }

        /// <summary>
        /// 获取指令(编号、订单类型、站台、状态)
        /// </summary>
        /// <returns></returns>
        public ASRSJOBResonse GetSingleASC(ASRSJOBQuery query)
        {
            //SELECT * from BT_WHSHY WHERE SHYCODE LIKE '1-11-01-01%' OR SHYCODE LIKE '1-11-01-02%' ORDER BY SHYID ASC
            //查询语句
            var sql = string.Format("SELECT * from asrsjob WHERE {0} And STATE=0 ORDER BY Id ASC LIMIT 0,1", query.Where);
            //查询
            var asrsjob = DBContext.Sql(sql)
                                .QuerySingle<ASRSJOBResonse>();
            if (asrsjob == null)
                return null;
            if (query.Type.Contains(asrsjob.TYPE))
                return asrsjob;
            else
                return null;
        }

        /// <summary>
        /// 获取指令列表
        /// </summary>
        /// <param name="status">状态</param>
        /// <returns></returns>
        public List<ASRSJOBResonse> GetList(ASRSJOBQuery query)
        {
            var list = DBContext.Select<ASRSJOBResonse>("*").From("asrsjob");

            Action<string, string, object> setWhere = (@where, name, value) => list.AndWhere(@where).Parameter(name, value);

            if (string.IsNullOrEmpty(query.ORIPORT))
            {
                setWhere("ORIPORT = @ORIPORT", "ORIPORT", query.ORIPORT);
            }

            return list.QueryMany();
        }

        /// <summary>
        /// 更新状态
        /// </summary>
        /// <param name="id">编号</param>
        /// <param name="status">状态</param>
        /// <returns></returns>
        public JResult UpdateStatus(int id, int status)
        {
            var result = new JResult()
            {
                Success = false
            };

            try
            {
                var asrsJob = DBContext.Sql("select * from asrsjob where Id=@Id")
                                    .Parameter("Id", id)
                                    .QuerySingle<ASRSJOBResonse>();
                if (asrsJob != null)
                {
                    DBContext.Sql("update t_inventory set Status = @Status where ResourceId = @ResourceId")
                            .Parameter("Status", 2)
                            .Parameter("ResourceId", asrsJob.BINDID)
                            .Execute();
                }

                var executeStatus = DBContext.Sql("update asrsjob set STATE = @STATE where ID = @ID")
                                .Parameter("STATE", status)
                                .Parameter("ID", id)
                                .Execute();

                if (executeStatus <= 0)
                {
                    throw new Exception("更新状态.");
                }


                result.Message = "操作成功.";
                result.Success = true;
            }
            catch (Exception ex)
            {
                result.Message = ex.Message;
            }

            return result;
        }

        /// <summary>
        /// 出库完成
        /// </summary>
        /// <param name="id">编号</param>
        /// <returns></returns>
        public JResult DeliveryCompleted(int id, int completeMode)
        {
            var result = new JResult()
            {
                Success = false
            };
            using (var tran = new TransactionProvider())
            {
                try
                {
                    var deliveryCompleted = DBContext.Sql("select j.Id AS JobId,j.Type,j.ORIPORT,j.TARPORT,i.ResourceId,i.SourceId,i.OrderType,i.id as InventoryId,i.WarehouseUnitId,j.STATE from asrsjob j INNER JOIN t_inventory i on j.BINDID=i.ResourceId WHERE j.Id=@Id")
                                        .Parameter("Id", id)
                                        .QuerySingle<DeliveryCompletedResponse>();

                    if (deliveryCompleted != null)
                    {
                        if (deliveryCompleted.STATE == (int)WorkStatus.Two)
                            throw new Exception("该指令已完成,不能操作.");

                        #region 更新任务状态成功
                        {
                            var updateJobStatus = DBContext.Sql("update asrsjob set STATE = 2 where id = @id")
                                        .Parameter("id", id)
                                        .Execute();
                            if (updateJobStatus <= 0)
                            {
                                var log = new Log()
                                {
                                    Level = 10,
                                    Source = 10,
                                    Message = $"更新任务({deliveryCompleted.ResourceId})状态成功.",
                                    Ip = "127.0.0.1",
                                    CreatedBy = 2,
                                    CreatedDate = DateTime.Now
                                };

                                DBContext.Insert<Log>("log", log)
                                    .AutoMap(x => x.Id)
                                    .ExecuteReturnLastId<int>();
                            }
                        }
                        #endregion

                        if (deliveryCompleted.OrderType == (int)InventoryType.出库)
                        {
                            #region 释放库位
                            var updateWarehouseunitStatus = DBContext.Sql("update t_warehouseunit set Locked = 0 where Id = @Id")
                                    .Parameter("Id", deliveryCompleted.WarehouseUnitId)
                                    .Execute();
                            if (updateWarehouseunitStatus <= 0)
                            {
                                var log = new Log()
                                {
                                    Level = 10,
                                    Source = 10,
                                    Message = $"解锁库位({deliveryCompleted.WarehouseUnitId})失败.",
                                    Ip = "127.0.0.1",
                                    CreatedBy = 2,
                                    CreatedDate = DateTime.Now
                                };
                                DBContext.Insert<Log>("log", log)
                                    .AutoMap(x => x.Id)
                                    .ExecuteReturnLastId<int>();
                            }
                            #endregion

                            #region 更新来源单据
                            {
                                var inventorystatus = DBContext.Sql("update t_inventory set InventoryQty=0,Disable=0 where ResourceId=@ResourceId")
                                       .Parameter("ResourceId", deliveryCompleted.SourceId)
                                       .Execute();
                                if (inventorystatus <= 0)
                                {
                                    var log = new Log()
                                    {
                                        Level = 10,
                                        Source = 10,
                                        Message = $"更新来源单据({deliveryCompleted.ResourceId})失败.",
                                        Ip = "127.0.0.1",
                                        CreatedBy = 2,
                                        CreatedDate = DateTime.Now
                                    };
                                    DBContext.Insert<Log>("log", log)
                                        .AutoMap(x => x.Id)
                                        .ExecuteReturnLastId<int>();
                                }
                            }
                            #endregion

                            #region 更新库存
                            {
                                var inventorystatus = DBContext.Sql("update t_inventory set InventoryQty=0,Status=2 where ResourceId = @ResourceId")
                                        .Parameter("ResourceId", deliveryCompleted.ResourceId)
                                        .Execute();
                                if (inventorystatus <= 0)
                                {
                                    var log = new Log()
                                    {
                                        Level = 10,
                                        Source = 10,
                                        Message = $"更新单据({deliveryCompleted.ResourceId})失败.",
                                        Ip = "127.0.0.1",
                                        CreatedBy = 2,
                                        CreatedDate = DateTime.Now
                                    };
                                    DBContext.Insert<Log>("log", log)
                                        .AutoMap(x => x.Id)
                                        .ExecuteReturnLastId<int>();
                                }
                            }
                            #endregion
                        }
                        else if (deliveryCompleted.OrderType == (int)InventoryType.入库)
                        {
                            #region 更新库存
                            {
                                var inventorystatus = DBContext.Sql("update t_inventory set Status=2 where ResourceId = @ResourceId")
                                        .Parameter("ResourceId", deliveryCompleted.ResourceId)
                                        .Execute();
                                if (inventorystatus <= 0)
                                {
                                    var log = new Log()
                                    {
                                        Level = 10,
                                        Source = 10,
                                        Message = $"更新单据({deliveryCompleted.ResourceId})失败.",
                                        Ip = "127.0.0.1",
                                        CreatedBy = 2,
                                        CreatedDate = DateTime.Now
                                    };
                                    DBContext.Insert<Log>("log", log)
                                        .AutoMap(x => x.Id)
                                        .ExecuteReturnLastId<int>();
                                }
                            }
                            #endregion
                        }

                        #region 删除任务
                        {
                            var deleteJobStatus = DBContext.Delete("asrsjob")
                            .Where("Id", id)
                            .Execute();

                            if (deleteJobStatus <= 0)
                            {
                                var log = new Log()
                                {
                                    Level = 10,
                                    Source = 10,
                                    Message = $"删除任务({deliveryCompleted.JobId})失败.",
                                    Ip = "127.0.0.1",
                                    CreatedBy = 2,
                                    CreatedDate = DateTime.Now
                                };
                                DBContext.Insert<Log>("log", log)
                                    .AutoMap(x => x.Id)
                                    .ExecuteReturnLastId<int>();
                            }
                        }
                        #endregion

                        #region 模式
                        {
                            var message = "";

                            if (completeMode == (int)CompleteMode.手动)
                                message = $"手动完成({deliveryCompleted.Type}) 单据号:{deliveryCompleted.ResourceId} 仓位：{deliveryCompleted.ORIPORT}~{deliveryCompleted.TARPORT}";
                            else
                                message = $"自动完成({deliveryCompleted.Type}) 单据号:{deliveryCompleted.ResourceId} 仓位：{deliveryCompleted.ORIPORT}~{deliveryCompleted.TARPORT}";

                            var log = new Log()
                            {
                                Level = 10,
                                Source = 10,
                                Message = message,
                                Ip = "127.0.0.1",
                                CreatedBy = 2,
                                CreatedDate = DateTime.Now
                            };

                            var logStatus = DBContext.Insert<Log>("log", log)
                                .AutoMap(x => x.Id)
                                .ExecuteReturnLastId<int>();
                        }
                        #endregion

                        tran.Commit();
                    }

                    result.Success = true;
                }
                catch (Exception ex)
                {
                    tran.Rollback();
                    result.Message = ex.Message;
                }
            }

            return result;
        }

        /// <summary>
        /// 删除
        /// </summary>
        public JResult Delete(int id)
        {
            var result = new JResult()
            {
                Success = false
            };

            using (var tran = new TransactionProvider())
            {
                try
                {
                    var asrsJob = DBContext.Sql("select * from asrsjob where Id=@Id")
                                    .Parameter("Id", id)
                                    .QuerySingle<ASRSJOBResonse>();

                    if (asrsJob == null)
                    {
                        return new JResult()
                        {
                            Success = false
                        };
                    }
                    if (asrsJob.STATE == (int)WorkStatus.Two)
                        throw new Exception("该指令已完成,不能操作.");

                    var inventorys = DBContext.Sql("select * from t_inventory where ResourceId=@ResourceId")
                                    .Parameter("ResourceId", asrsJob.BINDID)
                                    .QueryMany<InventoryResponse>();

                    var inventory = inventorys.FirstOrDefault();

                    if (inventory == null)
                    {
                        return new JResult()
                        {
                            Success = false
                        };
                    }

                    if (asrsJob.TYPE == "In")
                    {
                        //解锁库存
                        var updateWarehouseunitStatus = DBContext.Sql("update t_warehouseunit set Locked = @Locked where Id = @Id")
                                .Parameter("Locked", (int)Locked.否)
                                .Parameter("Id", inventory.WarehouseUnitId)
                                .Execute();
                        if (updateWarehouseunitStatus <= 0)
                            throw new Exception("解锁库存失败.");
                        //删除库存
                        var deleteInventoryStatus = DBContext.Delete("t_inventory")
                            .Where("ResourceId", asrsJob.BINDID)
                            .Execute();
                        if (deleteInventoryStatus <= 0)
                            throw new Exception("删除库存失败.");
                        //删除任务
                        //var deleteStatus = DBContext.Delete("asrsjob")
                        //    .Where("Id", asrsJob.Id)
                        //    .Execute();
                        //if (deleteStatus <= 0)
                        //    throw new Exception("删除任务失败.");

                        var log = new Log()
                        {
                            Level = 10,
                            Source = 10,
                            Message = $"手动删除({asrsJob.TYPE}) 单据编号:{inventory.ResourceId} 入库仓位:{asrsJob.ORIPORT}~{asrsJob.TARPORT}",
                            Ip = "127.0.0.1",
                            CreatedDate = DateTime.Now
                        };

                        var logStatus = DBContext.Insert<Log>("log", log)
                            .AutoMap(x => x.Id)
                            .ExecuteReturnLastId<int>();
                        if (logStatus <= 0)
                            throw new Exception("新增日志失败.");
                    }
                    else if (asrsJob.TYPE == "Out")
                    {
                        //解锁库存
                        var updateWarehouseunitStatus = DBContext.Sql("update t_warehouseunit set Locked = @Locked where Id = @Id")
                                .Parameter("Locked", (int)Locked.是)
                                .Parameter("Id", inventory.WarehouseUnitId)
                                .Execute();
                        if (updateWarehouseunitStatus <= 0)
                            throw new Exception("解锁库存失败.");
                        //更新入库单
                        var inventorystatus = DBContext.Sql("update t_inventory set InventoryQty = Qty where ResourceId = @ResourceId")
                                .Parameter("ResourceId", inventory.SourceId)
                                .Execute();
                        if (inventorystatus <= 0)
                            throw new Exception("出入库单据完成失败.");
                        //删除出库库存
                        var deleteInventoryStatus = DBContext.Delete("t_inventory")
                            .Where("ResourceId", asrsJob.BINDID)
                            .Execute();
                        if (deleteInventoryStatus <= 0)
                            throw new Exception("删除出库单失败.");
                        //删除任务
                        //var deleteStatus = DBContext.Delete("asrsjob")
                        //    .Where("Id", asrsJob.Id)
                        //    .Execute();
                        //if (deleteStatus <= 0)
                        //    throw new Exception("删除任务失败.");

                        var log = new Log()
                        {
                            Level = 10,
                            Source = 10,
                            Message = $"手动删除({asrsJob.TYPE}) 单据编号:{inventory.ResourceId} 入库仓位:{asrsJob.ORIPORT}~{asrsJob.TARPORT}",
                            Ip = "127.0.0.1",
                            CreatedDate = DateTime.Now
                        };

                        var logStatus = DBContext.Insert<Log>("log", log)
                            .AutoMap(x => x.Id)
                            .ExecuteReturnLastId<int>();
                        if (logStatus <= 0)
                            throw new Exception("新增日志失败.");
                    }

                    tran.Commit();

                    result.Success = true;
                }
                catch (Exception ex)
                {
                    tran.Rollback();
                    result.Message = ex.Message;
                }

                return result;
            }
        }

        /// <summary>
        /// 转历史
        /// </summary>
        public JResult TransferHistory()
        {
            var result = new JResult()
            {
                Success = false
            };

            using (var tran = new TransactionProvider())
            {
                try
                {
                    var asrsJobs = DBContext.Sql("select * from asrsjob where STATE=@STATE")
                                    .Parameter("STATE", (int)ASRSJOBStatus.完成)
                                    .QueryMany<ASRSJOBResonse>();

                    if (asrsJobs == null || !asrsJobs.Any())
                        return new JResult()
                        {
                            Success = true
                        };
                    var asrsJob = asrsJobs.FirstOrDefault();
                    if (asrsJob != null)
                    {
                        //删除任务
                        var deleteStatus = DBContext.Delete("asrsjob")
                            .Where("Id", asrsJob.Id)
                            .Execute();
                        if (deleteStatus <= 0)
                            throw new Exception("删除任务失败.");
                    }

                    tran.Commit();

                    result.Success = true;
                }
                catch (Exception ex)
                {
                    tran.Rollback();
                    result.Message = ex.Message;
                }

                return result;
            }
        }

        /// <summary>
        /// 获取指令列表
        /// </summary>
        /// <returns></returns>
        public List<ASRSJOBQueryResponse> ASRSJOBPager(ASRSJOBQuery query)
        {
            var files = @"ID,
BINDID,
TYPE,
CTNCODE,
ORIPORT,
TARPORT,
STATE,
CREATEDATE,
STATIONID";
            var tableName = "asrsjob";
            var orderby = "ORDER BY CREATEDATE ASC";
            var where = "where 1=1";

            #region 条件
            if (query.States.Any())
            {
                where += string.Format(" and STATE in({0})", string.Join(",", query.States));
            }
            #endregion

            //查询Sql
            var querySql = string.Format("select {0} from {1} {2} {3}", files, tableName, where, orderby);
            //执行查询
            var list = DBContext.Sql(querySql)
                                .QueryMany<ASRSJOBQueryResponse>();

            return list;
        }
    }
}
